﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Xwltz.Framework.Helper
{
    public class HttpHelper
    {
        public readonly string AppKey = "";

        public static string HttpPost(string url, IDictionary<string, string> parameters, string contentType = "application/json;charset=UTF-8")
        {
            HttpWebResponse rsp = null;
            Stream reqStream = null;
            try
            {
                var req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "Post";
                req.KeepAlive = false;
                req.ProtocolVersion = HttpVersion.Version10;
                req.Timeout = 5000;
                req.ContentType = contentType;
                req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37";
                var postData = Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));
                req.ContentLength = postData.Length;
                reqStream = req.GetRequestStream();
                reqStream.Write(postData, 0, postData.Length);
                rsp = (HttpWebResponse)req.GetResponse();
                if (rsp.CharacterSet == null) return "";
                var encoding = Encoding.GetEncoding(rsp.CharacterSet);
                return GetResponseAsString(rsp, encoding);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                reqStream?.Close();
                rsp?.Close();
            }
        }

        public static string HttpPost(string url, IDictionary<string, string> parameters, string apiKey, string contentType)
        {
            HttpWebResponse rsp = null;
            Stream reqStream = null;
            try
            {
                var req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "Post";
                req.KeepAlive = false;
                req.ProtocolVersion = HttpVersion.Version10;
                req.Timeout = 5000;
                req.ContentType = contentType;
                if (!apiKey.IsNullOrEmpty())
                {
                    req.Headers.Add("Authorization", $"APIKEY {apiKey}");
                }
                var postData = Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));
                req.ContentLength = postData.Length;
                reqStream = req.GetRequestStream();
                reqStream.Write(postData, 0, postData.Length);
                rsp = (HttpWebResponse)req.GetResponse();
                if (rsp.CharacterSet == null) return "";
                var encoding = Encoding.GetEncoding(rsp.CharacterSet);
                return GetResponseAsString(rsp, encoding);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                reqStream?.Close();
                rsp?.Close();
            }
        }

        public static string HttpPost(string url, string json)
        {
            HttpWebResponse rsp = null;
            Stream reqStream = null;
            try
            {
                var req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "Post";
                req.KeepAlive = false;
                req.ProtocolVersion = HttpVersion.Version10;
                req.Timeout = 5000;
                req.ContentType = "application/json;charset=UTF-8";
                //req.Headers[HttpRequestHeader.Cookie] = "PreUrl=/adm/default.aspx; .ASPXAUTH=243B3CD13051DE57ECB5115FCD8E6F4C577A1A6CFA9FB62BA73CF2311AD5BA54EFA75DD5705828860962A65F1A431113F61BF8D6819C687BC950940D7A0E13A9DC13523848636176342BF66F5A9F7E46B9D7122DBAAD3839480ED979AAF04BD055C8EF612A38DEF32FE2E0BB482503AE27820A37F89BAC2BA322CD14794F25B735EA732B319353BA389F60D2374223EFED40DE8D8111467A0B13DE0932C89877B417F77903B2216DC95B58EA1701AD0499B03868FDE919E4F8A73E393CBEFD6FCFA9D0381BA132012887FA7A102886F93195A618B59E6F10462F27C1C374F74DCDCA32B8EB8196F2AA188E7C59F4C520";
                var postData = Encoding.UTF8.GetBytes(json);
                req.ContentLength = postData.Length;
                reqStream = req.GetRequestStream();
                reqStream.Write(postData, 0, postData.Length);
                rsp = (HttpWebResponse)req.GetResponse();
                if (rsp.CharacterSet == null) return "";
                var encoding = Encoding.GetEncoding(rsp.CharacterSet);
                return GetResponseAsString(rsp, encoding);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                reqStream?.Close();
                rsp?.Close();
            }
        }

        public static async Task<string> HttpPostAsync(string url, string parameters = "", string apiKey = "", string contentType = "application/json;charset=UTF-8")
        {
            HttpWebResponse response = null;
            Stream reqStream = null;
            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "Post";
                request.KeepAlive = false;
                request.ProtocolVersion = HttpVersion.Version10;
                request.Timeout = 15000;
                request.ContentType = contentType;
                if (!apiKey.IsNullOrEmpty())
                {
                    request.Headers.Add("token", $"APIKEY {apiKey}");
                }
                var postData = Encoding.UTF8.GetBytes(parameters == "" ? "{}" : parameters);
                request.ContentLength = postData.Length;
                reqStream = request.GetRequestStream();
                reqStream.Write(postData, 0, postData.Length);
                reqStream.Close();

                response = await request.GetResponseAsync() as HttpWebResponse;
                if (response?.CharacterSet == null) return "";
                var encoding = Encoding.GetEncoding(response.CharacterSet);
                return HttpHelper.GetResponseAsString(response, encoding);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                reqStream?.Close();
                response?.Close();
            }
        }

        public static string HttpGet(string url, IDictionary<string, string> parameters = null, string contentType = "application/json;charset=UTF-8")
        {
            HttpWebRequest request;
            if (parameters != null)
            {
                request = (HttpWebRequest)WebRequest.Create(url + "?" + BuildQuery(parameters, "utf8"));
            }
            else
            {
                request = (HttpWebRequest)WebRequest.Create(url);
            }

            request.Accept = "application/json, text/plain, */*";
            request.Connection = "keep-aliv";
            request.Method = "Get";
            request.ReadWriteTimeout = 5000;
            request.ContentType = contentType;
            //request.Host = "index.baidu.com";
            //request.Referer = "http://index.baidu.com/v2/index.html";
            request.UserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/90.0.4430.212";
            //request.Headers.Add("Cookie", @"BIDUPSID=4F24A55DE3728B99B7E2127F3E7FC334; BAIDUID=115B12EEB63E2DF638E0E112BDF41D08:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDSFRCVID=J4COJeC62GaQGroeT2qurYCEgeKhkhTTH6aoIg5Z5WbMLi8CJY-FEG0P8U8g0Kubr3hbogKKL2OTHmAF_2uxOjjg8UtVJeC6EG0Ptf8g0f5; H_BDCLCKID_SF=tJ-O_CP2tC_3f-tkej-bjPTH-UnLq-6a02OZ0lOVaq3OoMcmK4oZqf4iKRrm04b-Wa-OBfomWIQqEUnz5xTWQ5DSeqAtX4Q-3Kv4KKJxHlCWeIJo5t5_bl8nhUJiBMAHBan7WljIXKohJh7FM4tW3J0ZyxomtfQxtNRJ0DnjtnLhbCDwD5_ajTJMbfkX5RQHK4o2WDv7MqbcOR5Jj6Kby-5L0f6-X4TmMjrk5h5jWUofqtKG3MA--tRB2-Jw-tCHfgvhVIIy-x5nsq0x0hjYe-bQyp_Ly5jd2COMahv1tq7xOb6qQlPK5JkgMx6MqpQJQeQ-5KQN3KJmfbL9bT3YjjTXjHAJqTK8tJ3fL-08aP5jjn5NMtTjq4tehHRp2xc9WDTm_D_K5bo6J4QNWtC--RD4LPoMK6Lttj5X-pPKKRAaKqPwqfrYhtLV-H70XRo23mkjbnczfn02OP5P54T-L44syPRrJfRnWIjCKfA-b4ncjRcTehoM3xI8LNj405OTbIFO0KJzJCFKMDK9jjDMen-W5gTKbnOQ54o2WbC8Kbu3qP89XU6qLT5XQP5TBxTa5G5OBUO-ylOpeUL6Db3mjq0njxQyJ4KJ2mTXBn6vB-5sOUOmQfonDh8e2a7MJUntHCTx3h5O5hvv8KoO3M7VLfKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQbG_EJ5_jJn4f_D_QKRT5jtbNqRJqM4F_hl6354CXKKOLVhF20h7keq8CDxJH0f-XhUonJJot-H5mKR3HWbnOjMb2y5jHhUFsjJCtL-juBIKO5hcwHlQpsIJMeh_WbT8U5f5HJ-vaaKviah4-BMb1DqjDBT5h2M4qMxtOLR3pWDTm_q5TtUJMeCnTD-Dhe4tX-NFDt5ketfK; BDSFRCVID_BFESS=J4COJeC62GaQGroeT2qurYCEgeKhkhTTH6aoIg5Z5WbMLi8CJY-FEG0P8U8g0Kubr3hbogKKL2OTHmAF_2uxOjjg8UtVJeC6EG0Ptf8g0f5; H_BDCLCKID_SF_BFESS=tJ-O_CP2tC_3f-tkej-bjPTH-UnLq-6a02OZ0lOVaq3OoMcmK4oZqf4iKRrm04b-Wa-OBfomWIQqEUnz5xTWQ5DSeqAtX4Q-3Kv4KKJxHlCWeIJo5t5_bl8nhUJiBMAHBan7WljIXKohJh7FM4tW3J0ZyxomtfQxtNRJ0DnjtnLhbCDwD5_ajTJMbfkX5RQHK4o2WDv7MqbcOR5Jj6Kby-5L0f6-X4TmMjrk5h5jWUofqtKG3MA--tRB2-Jw-tCHfgvhVIIy-x5nsq0x0hjYe-bQyp_Ly5jd2COMahv1tq7xOb6qQlPK5JkgMx6MqpQJQeQ-5KQN3KJmfbL9bT3YjjTXjHAJqTK8tJ3fL-08aP5jjn5NMtTjq4tehHRp2xc9WDTm_D_K5bo6J4QNWtC--RD4LPoMK6Lttj5X-pPKKRAaKqPwqfrYhtLV-H70XRo23mkjbnczfn02OP5P54T-L44syPRrJfRnWIjCKfA-b4ncjRcTehoM3xI8LNj405OTbIFO0KJzJCFKMDK9jjDMen-W5gTKbnOQ54o2WbC8Kbu3qP89XU6qLT5XQP5TBxTa5G5OBUO-ylOpeUL6Db3mjq0njxQyJ4KJ2mTXBn6vB-5sOUOmQfonDh8e2a7MJUntHCTx3h5O5hvv8KoO3M7VLfKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQbG_EJ5_jJn4f_D_QKRT5jtbNqRJqM4F_hl6354CXKKOLVhF20h7keq8CDxJH0f-XhUonJJot-H5mKR3HWbnOjMb2y5jHhUFsjJCtL-juBIKO5hcwHlQpsIJMeh_WbT8U5f5HJ-vaaKviah4-BMb1DqjDBT5h2M4qMxtOLR3pWDTm_q5TtUJMeCnTD-Dhe4tX-NFDt5ketfK; Hm_lvt_d101ea4d2a5c67dab98251f0b5de24dc=1624418329,1624525580,1625474135,1625572156; bdindexid=lsgm5luqgsdjmvblkdcntmkev2; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; delPer=0; PSINO=3; BDUSS=N0cWhhc2dVdUdLUVN2bjRhOWE3SU1IcXJYMmtoQWR1NXFqNndXTktXczYxQXRoRVFBQUFBJCQAAAAAAAAAAAEAAAAko5oNeGlhbmd3ZWl4dWV3ZWkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpH5GA6R-RgWm; BDUSS_BFESS=N0cWhhc2dVdUdLUVN2bjRhOWE3SU1IcXJYMmtoQWR1NXFqNndXTktXczYxQXRoRVFBQUFBJCQAAAAAAAAAAAEAAAAko5oNeGlhbmd3ZWl4dWV3ZWkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpH5GA6R-RgWm; CHKFORREG=a0408822d2007a8f57023aeb8a3a825b; __yjs_st=2_MmUwNmVmNmQxYjA3NTM4YmFiNjYyOWQ0MWViODJmZTYyMzI2NTliMDg2M2NjMjY0NGNmZGUyNmMxY2M3NDk1NzliNWMwNmY3YWMxMzUxYTc3YTEyMDhhNWRmODdhYzVjOGZjZGYxOTM1ZTEyMjA1NzgyNzA0OWFkOWFlMDA2OTk0Y2ZlYmNjNzUxOWYzN2FjY2JhY2IxZjlkNjE4MGUxNzQ1MDgyYTBlZDljYzEyNjljNzI5NzYzMWExMWI5ZTZjNmY5ZDc4MTAwYTAyNWRlM2IwYjg2ZGJkNWJmNDZiMWU2NGY2ZGVhNzA5NWQ1Y2E0MzUwOTE2YzI3YjY3ZjYzNV83X2ExOGQ5NWY0; BAIDUID_BFESS=24332C88057ECFC889C180B743C184F5:FG=1; BA_HECTOR=85ahag05ak008584ej1ge8ic00q; RT=\""z=1&dm=baidu.com&si=j3znjieqmd&ss=kqs04o1u&sl=9&tt=6uy&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf\""; Hm_lpvt_d101ea4d2a5c67dab98251f0b5de24dc=1625573772; ab_sr=1.0.1_MzQwNWM0NzlhMzE4YjMyYjRhOWE2MmNiYWE4OGFhMjBlNzAwMzE5ZjM1NzIxYWFiMTZiOWQxNGY0ZDI1YTFhM2RmM2VkMDc1OTliZmU5YTRmMDhhNjA3M2FjMmZjM2Q0ZDQ4OTM3MWE4MTRmNTVlNmE4NGJjYzA3OWMwNmQwZThkZGNjMDA2NjA2MGEyZDFkYjZhNWRjNWViZWJjZmY3OA==");
            //request.ContentType = "text/html; charset=gbk";
            var response = (HttpWebResponse)request.GetResponse();
            var myResponseStream = response.GetResponseStream();
            if (myResponseStream == null) return "";
            var myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("gbk"));
            string strCookie = response.Headers["Set-Cookie"];
            var retString = myStreamReader.ReadToEnd();
            return retString;
        }

        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <param name="encode"></param>
        /// <returns>URL编码后的请求数据</returns>
        public static string BuildQuery(IDictionary<string, string> parameters, string encode = "utf-8")
        {
            var postData = new StringBuilder();
            var hasParam = false;
            if (parameters == null) return postData.ToString();
            var dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                var name = dem.Current.Key;
                var value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (string.IsNullOrEmpty(name)) continue;
                if (hasParam)
                {
                    postData.Append("&");
                }
                postData.Append(name);
                postData.Append("=");
                switch (encode)
                {
                    case "gb2312":
                        postData.Append(HttpUtility.UrlEncode(value, Encoding.GetEncoding("gb2312")));
                        break;

                    case "utf8":
                        postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                        break;

                    default:
                        postData.Append(value);
                        break;
                }
                hasParam = true;
            }
            dem.Dispose();
            return postData.ToString();
        }

        /// <summary>
        /// 把响应流转换为文本。
        /// </summary>
        /// <param name="rsp">响应流对象</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>响应文本</returns>
        public static string GetResponseAsString(WebResponse rsp, Encoding encoding)
        {
            Stream stream = null;
            StreamReader reader = null;
            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                if (stream != null) reader = new StreamReader(stream, encoding);
                if (reader != null) return reader.ReadToEnd();
            }
            finally
            {
                // 释放资源
                reader?.Close();
                stream?.Close();
                rsp?.Close();
            }
            return "";
        }
    }
}